#include "AST.h"

DesignEntityTable AST::designEntityTable = DesignEntityTable();

AST::AST(Node* node){
	this->root = node;
}

void AST::setRoot(Node* node){
	this->root = node;
}

Node* AST::getRoot(){
	return this->root;
}

AST AST::getSubTree(int nodeID){
	Node* node = NULL;
	if (nodeID == this->root->getNodeID()){
		node = this->root;
	}else if(nodeID > this->root->getNodeID()){
		node = checkDescendants(this->root, nodeID);
	}
	if (node == NULL) return NULL;
	return AST(node);
}

Node* AST::checkDescendants(Node* node, int nodeID){
	vector<Node*> children = node->getChildren();
	if(children.empty()) return NULL;
	Node* nextCheck = NULL;
	for(vector<Node*>::iterator it = children.begin(); it != children.end(); it++){
		if ((*it)->getNodeID() <= nodeID){ 
			nextCheck = *it;
		}
	}
	if(nextCheck->getNodeID() == nodeID){
		return nextCheck;
	}else{
		return checkDescendants(nextCheck, nodeID);
	}
}

bool AST::equals(AST* otherAST) {
	return compareSubTree(this->getRoot(), otherAST->getRoot());
}

bool AST::compareSubTree(Node* node1, Node* node2) {
	if (node1->equals(node2)) {
		vector<Node*> children1 = node1->getChildren();
		vector<Node*> children2 = node2->getChildren();
		int vectorSize=children1.size();
		if (vectorSize==children2.size()) {
			for (int i=0; i<vectorSize; i++) {
				if (compareSubTree(children1[i], children2[i])) {
				} else {
					return false;
				}
			}
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

void AST::addToDETable(Node* node){
	SyntacticType sType = node->getDesignEntity()->getType();
	switch(sType){
	case ASSIGN:
		AST::designEntityTable.addAssignDe(node);
		break;
	case CONSTANT:
		AST::designEntityTable.addConstantDe(node);
		break;
	case IF:
		AST::designEntityTable.addIfDe(node);
		break;
	case WHILE:
		AST::designEntityTable.addWhileDe(node);
		break;
	default:
		break;
	}
	return;
}

DesignEntityTable* AST::getDesignEntityTable(){
	return &AST::designEntityTable;
}